package template

import (
	"io/ioutil"
	"os"
)

type queueKind struct{}

func (k *queueKind) Kind() string {
	return "queue"
}

func (k *queueKind) Gen(rootDir string) error {
	var err error
	rootDir += "/" + *projectRepo + "-consumer"
	err = os.MkdirAll(rootDir, 0775)
	if err != nil {
		return err
	}
	common := new(commonKind)
	err = common.Gen(rootDir)
	if err != nil {
		return err
	}
	// go mod
	{
		modData := projectReplacer.Replace(templateQueueGoMod)
		modData = versionReplacer.Replace(modData)
		err := ioutil.WriteFile(rootDir+"/go.mod", []byte(modData), 0666)
		if err != nil {
			return err
		}
	}
	// etc
	{
		etcDir := rootDir + "/etc"
		err := os.MkdirAll(etcDir, 0775)
		if err != nil {
			return err
		}
		etcAppIni := etcDir + "/app.ini.example"
		dataIni := projectReplacer.Replace(templateQueueEtcAppIniExample)
		err = ioutil.WriteFile(etcAppIni, []byte(dataIni), 0666)
		if err != nil {
			return err
		}
		etcAppDockerIni := etcDir + "/app-docker.ini.example"
		dataDockerIni := projectReplacer.Replace(templateQueueEtcAppDockerIniExample)
		err = ioutil.WriteFile(etcAppDockerIni, []byte(dataDockerIni), 0666)
		if err != nil {
			return err
		}
	}
	// startup
	{
		startupDir := rootDir + "/startup"
		registerData := projectReplacer.Replace(templateQueueStartupRegister)
		registerData = projectProtoReplacer.Replace(registerData)
		err = ioutil.WriteFile(startupDir+"/register.go", []byte(registerData), 0666)
		if err != nil {
			return err
		}
		configData := projectReplacer.Replace(templateQueueStartupConfig)
		err = ioutil.WriteFile(startupDir+"/config.go", []byte(configData), 0666)
		if err != nil {
			return err
		}
	}
	// repository
	{
		repositoryDir := rootDir + "/repository"
		err = os.MkdirAll(repositoryDir, 0775)
		if err != nil {
			return err
		}
		err := ioutil.WriteFile(repositoryDir+"/repository.go", []byte("package repository"), 0666)
		if err != nil {
			return err
		}
	}
	// vars
	{
		varsDir := rootDir + "/vars"
		err := os.MkdirAll(varsDir, 0775)
		if err != nil {
			return err
		}
		err = ioutil.WriteFile(varsDir+"/settings.go", []byte(templateQueueVarsSettings), 0666)
		if err != nil {
			return err
		}
		err = ioutil.WriteFile(varsDir+"/vars.go", []byte(templateQueueVarsVars), 0666)
		if err != nil {
			return err
		}
	}
	// service
	{
		serviceDir := rootDir + "/service"
		err = os.MkdirAll(serviceDir, 0775)
		if err != nil {
			return err
		}
		serviceData := projectReplacer.Replace(templateQueueService)
		err = ioutil.WriteFile(serviceDir+"/"+*projectRepo+".go", []byte(serviceData), 0666)
		if err != nil {
			return err
		}
	}
	// main.go
	{
		mainData := projectReplacer.Replace(templateQueueMain)
		err := ioutil.WriteFile(rootDir+"/main.go", []byte(mainData), 0666)
		if err != nil {
			return err
		}
	}

	return nil
}

const (
	templateQueueMain = `package main

import (
	"{namespace}/{service_name}/startup"
	"gitee.com/kelvins-io/kelvins"
	"gitee.com/kelvins-io/kelvins/app"
)

const APP_NAME = "{service_name}"

func main() {
	application := &kelvins.QueueApplication{
		Application: &kelvins.Application{
			LoadConfig: startup.LoadConfig,
			SetupVars:  startup.SetupVars,
			StopFunc:   startup.StopFunc,
			Name:       APP_NAME,
		},
		GetNamedTaskFuncs: startup.GetNamedTaskFuncs,
	}
	app.RunQueueApplication(application)
}
`
	templateQueueService = `package service

import (
	"context"
	"log"
	"strings"
	"{namespace}/{service_name}/util/email"
	"{namespace}/{service_name}/vars"
)

func NoticeConsume(ctx context.Context, body string) error {
	err := email.SendEmailNotice(context.TODO(), strings.Join(vars.EmailNoticeSetting.Receivers, ","), "{service_name}", "{service_name} NoticeConsume " + body)
	if err != nil {
		log.Printf("send email to(%+v) err %v\n", vars.EmailNoticeSetting, err)
	}
	return err
}

func NoticeConsumeErr(ctx context.Context, err, body string) error {
	return nil
}
`
	templateQueueVarsVars = `package vars

var (
	EmailNoticeSetting *EmailNoticeSettingS
	EmailConfigSetting *EmailConfigSettingS
)

`
	templateQueueVarsSettings = `package vars

type EmailConfigSettingS struct {
	User     string
	Password string
	Host     string
	Port     string
}

type EmailNoticeSettingS struct {
	Receivers []string
}
`
	templateQueueStartupRegister = `package startup

import "{namespace}/{service_name}/service"

const (
	TaskNameNotice    = "kelvins-template_notice"
	TaskNameNoticeErr = "kelvins-template_notice_err"
)

func GetNamedTaskFuncs() map[string]interface{} {

	var taskRegister = map[string]interface{}{
		TaskNameNotice:    service.NoticeConsume,
		TaskNameNoticeErr: service.NoticeConsumeErr,
	}
	return taskRegister
}
`
	templateQueueStartupConfig = `package startup

import (
	"{namespace}/{service_name}/vars"
	"gitee.com/kelvins-io/kelvins/config"
)

const (
	SectionEmailConfig = "email-config"
	SectionEmailNotice = "email-notice"
)

// LoadConfig 加载配置对象映射
func LoadConfig() error {
	// 邮箱
	vars.EmailConfigSetting = new(vars.EmailConfigSettingS)
	config.MapConfig(SectionEmailConfig, vars.EmailConfigSetting)
	
	vars.EmailNoticeSetting = new(vars.EmailNoticeSettingS)
	config.MapConfig(SectionEmailNotice, vars.EmailNoticeSetting)
	return nil
}
`
	templateQueueEtcAppDockerIniExample = `[kelvins-server]
Environment = "dev"

[kelvins-logger]
RootPath = "./logs"
Level = "debug"

[kelvins-mysql]
Host = "mysql5_7:3306"
UserName = "root"
Password = "xxx"
DBName = "{service_name}"
Charset = "utf8"
PoolNum =  10
MaxIdleConns = 5
ConnMaxLifeSecond = 3600
MultiStatements = true
ParseTime = true

[kelvins-redis]
Host = "redis:6379"
Password = "oyuioyiuoyui"
DB = 1
PoolNum = 10


[kelvins-queue-server]
CustomQueueList = "{service_name}_notice"
WorkerConcurrency = 3


[kelvins-queue-amqp]
Broker = "amqp://root:micro-mall@rabbitmq:5672/micro-mall"
DefaultQueue = "kelvins-template_notice"
ResultBackend = "redis://oyuioyiuoyui@redis:6379/8"
ResultsExpireIn = 3600
Exchange = "kelvins-template_notice"
ExchangeType = "direct"
BindingKey = "kelvins-template_notice"
PrefetchCount = 3
TaskRetryCount = 3
TaskRetryTimeout = 60

[email-config]
User = "urtyu@qq.com"
Password = "urtyiirtirty"
Host = "smtp.qq.com"
Port = "465"

[email-notice]
Receivers = "xx@qq.com"`

	templateQueueEtcAppIniExample = `[kelvins-server]
Environment = "dev"

[kelvins-logger]
RootPath = "./logs"
Level = "debug"

[kelvins-mysql]
Host = "127.0.0.1:3306"
UserName = "root"
Password = "xxx"
DBName = "xxxx"
Charset = "utf8"
PoolNum =  10
MaxIdleConns = 5
ConnMaxLifeSecond = 3600
MultiStatements = true
ParseTime = true

[kelvins-redis]
Host = "127.0.0.1:6379"
Password = "xxxx"
DB = 1
PoolNum = 10


[kelvins-queue-server]
CustomQueueList = "kelvins-template_notice"
WorkerConcurrency = 1


[kelvins-queue-amqp]
Broker = "amqp://micro-mall:szJ9aePR@127.0.0.1:5672/micro-mall"
DefaultQueue = "kelvins-template_notice"
ResultBackend = "redis://xxx@127.0.0.1:6379/8"
ResultsExpireIn = 3600
Exchange = "kelvins-template_notice"
ExchangeType = "direct"
BindingKey = "kelvins-template_notice"
PrefetchCount = 3
TaskRetryCount = 3
TaskRetryTimeout = 60

[email-config]
User = "xxx@qq.com"
Password = "xxxx"
Host = "smtp.qq.com"
Port = "465"

[email-notice]
Receivers = "610905744@qq.com"`

	templateQueueGoMod = `module {namespace}/{service_name}

go 1.13

require (
	gitee.com/kelvins-io/common {version_common}
	gitee.com/kelvins-io/kelvins {version_kelvins}
	google.golang.org/grpc v1.34.0
)`
)
